home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 7 / BBS in a Box - Macintosh - Volume VII (BBS in a Box) (January 1993).iso / Files / Art / P / PhotoShopDev.cpt / PhotoShopDev / Acq-Think C 4.0 / DummyScan.c < prev    next >
Text File  |  1990-02-13  |  11KB  |  596 lines

  1. /*
  2.     File: DummyScan.c
  3.  
  4.     Copyright 1990 by Thomas Knoll.
  5.  
  6.     Think C source file for DummyScan example.
  7. */
  8.  
  9. #include <MacTypes.h>
  10. #include <MemoryMgr.h>
  11. #include <ResourceMgr.h>
  12. #include <Quickdraw.h>
  13. #include <ControlMgr.h>
  14. #include <DialogMgr.h>
  15. #include <OSUtil.h>
  16. #include <PackageMgr.h>
  17. #include <SysErr.h>
  18. #include <ToolboxUtil.h>
  19. #include <pascal.h>
  20. #include <SetUpA4.h>
  21.  
  22. #include "AcquireInterface.h"
  23.  
  24. #define nil 0L
  25. #define Length(string) (*(unsigned char *)(string))
  26.  
  27. /* The value of global variables are not preserved between invocations
  28.    of the plug-in, since the plug-in's resource file is closed. To keep
  29.    values around longer, make them part of the following structure. */
  30.  
  31. typedef struct TPermanent {
  32.     short lastRows;
  33.     short lastCols;
  34.     short lastMode;
  35.     } TPermanent;
  36.  
  37. TPermanent gPermanent;
  38.  
  39. short gResult;
  40. AcquireRecordPtr gStuff;
  41.  
  42. short gNextRow;
  43. short gNextPlane;
  44.  
  45. /*****************************************************************************/
  46.  
  47. /* Calls the host's TestAbort function */
  48.  
  49. Boolean TestAbort (void)
  50.  
  51.     {
  52.     return CallPascalB (gStuff->abortProc);
  53.     }
  54.  
  55. /*****************************************************************************/
  56.  
  57. /* Calls the host's UpdateProgress procedure */
  58.  
  59. void UpdateProgress (done, total)
  60.  
  61. long done;
  62. long total;
  63.  
  64.     {
  65.     CallPascal (done, total, gStuff->progressProc);
  66.     }
  67.  
  68. /*****************************************************************************/
  69.  
  70. /* Sets the global variables to their default values. */
  71.  
  72. void InitGlobals (void)
  73.  
  74.     {
  75.     gPermanent.lastRows = 256;
  76.     gPermanent.lastCols = 256;
  77.     gPermanent.lastMode = acquireModeRGBColor;
  78.     }
  79.  
  80. /*****************************************************************************/
  81.  
  82. /* Centers a dialog template 1/3 of the way down on the main screen. */
  83.  
  84. void CenterDialog (dt)
  85.  
  86. DialogTHndl dt;
  87.  
  88. #define menuHeight 20
  89.  
  90.     {
  91.     Rect r;
  92.     short width;
  93.     short height;
  94.  
  95.     width  = screenBits.bounds.right;
  96.     height = screenBits.bounds.bottom;
  97.  
  98.     r = (**dt).boundsRect;
  99.     OffsetRect (&r, -r.left, -r.top);
  100.     OffsetRect (&r, (width - r.right) / 2,
  101.                     (height - r.bottom - menuHeight) / 3 + menuHeight);
  102.     (**dt).boundsRect = r;
  103.     }
  104.  
  105. #undef menuHeight
  106.  
  107. /*****************************************************************************/
  108.  
  109. /* Displays the about dialog box for the plug-in module. */
  110.  
  111. void DoAbout (void)
  112.  
  113. #define dialogID 16000
  114.  
  115.     {
  116.     short item;
  117.     DialogPtr dp;
  118.     DialogTHndl dt;
  119.  
  120.     dt = (DialogTHndl) GetResource ('DLOG', dialogID);
  121.     HNoPurge ((Handle) dt);
  122.     CenterDialog (dt);
  123.  
  124.     dp = GetNewDialog (dialogID, nil, (WindowPtr) -1);
  125.  
  126.     ModalDialog (nil, &item);
  127.  
  128.     DisposDialog (dp);
  129.     HPurge ((Handle) dt);
  130.     }
  131.  
  132. #undef dialogID
  133.  
  134. /*****************************************************************************/
  135.  
  136. /* Prepare to acquire an image.  If the plug-in module needs only a limited
  137.    amount of memory, it can lower the value of the 'maxData' field. */
  138.  
  139. void DoPrepare (void)
  140.  
  141.     {
  142.     if (gStuff->maxData > 0x80000)
  143.         gStuff->maxData = 0x80000;
  144.     }
  145.  
  146. /*****************************************************************************/
  147.  
  148. /* UserItem to outline the OK button in a dialog box. */
  149.  
  150. pascal void OutlineOK (dp, item)
  151.  
  152. DialogPtr dp;
  153. short item;
  154.  
  155.     {
  156.     Rect r;
  157.     Handle h;
  158.     short itemType;
  159.     
  160.     SetUpA4 ();
  161.  
  162.     item = OK;
  163.  
  164.     GetDItem (dp, item, &itemType, &h, &r);
  165.  
  166.     PenNormal ();
  167.     PenSize (3, 3);
  168.     
  169.     InsetRect (&r, -4, -4);
  170.     FrameRoundRect (&r, 16, 16);
  171.  
  172.     PenNormal ();
  173.     
  174.     RestoreA4 ();
  175.     }
  176.  
  177. /*****************************************************************************/
  178.  
  179. /* Converts a string to a number between 1 and 30000.
  180.    Returns false if not a valid number or out of range. */
  181.  
  182. Boolean ConvertString (s, n)
  183.  
  184. Str255 s;
  185. short *n;
  186.  
  187.     {
  188.     long x;
  189.     short j;
  190.  
  191.     for (j = 1; j <= Length (s); j++)
  192.         if (s [j] < '0' || s [j] > '9')
  193.             return false;
  194.  
  195.     StringToNum (s, &x);
  196.  
  197.     if (x < 1 || x > 30000)
  198.         return false;
  199.  
  200.     *n = x;
  201.  
  202.     return true;
  203.     }
  204.  
  205. /*****************************************************************************/
  206.  
  207. /* Prompt the user for the image parameters.
  208.    Returns false if the user cancels. */
  209.  
  210. Boolean GetParameters (rows, cols, mode)
  211.  
  212. short *rows;
  213. short *cols;
  214. short *mode;
  215.  
  216. #define dialogID  16001
  217. #define hookItem  3
  218. #define rowsItem  4
  219. #define colsItem  5
  220. #define bModeItem 6
  221. #define gModeItem 7
  222. #define iModeItem 8
  223. #define cModeItem 9
  224.  
  225.     {
  226.     Rect r;
  227.     Str255 s;
  228.     Handle h;
  229.     short item;
  230.     DialogPtr dp;
  231.     DialogTHndl dt;
  232.     short itemType;
  233.     Handle rowsText;
  234.     Handle colsText;
  235.     ControlHandle gButton;
  236.     ControlHandle bButton;
  237.     ControlHandle iButton;
  238.     ControlHandle cButton;
  239.  
  240.     dt = (DialogTHndl) GetResource ('DLOG', dialogID);
  241.     HNoPurge ((Handle) dt);
  242.     CenterDialog (dt);
  243.  
  244.     dp = GetNewDialog (dialogID, nil, (WindowPtr) -1);
  245.     
  246.     RememberA4 ();
  247.  
  248.     GetDItem (dp, hookItem, &itemType, &h                  , &r);
  249.     SetDItem (dp, hookItem,  itemType, (Handle) &OutlineOK, &r);
  250.  
  251.     GetDItem (dp, rowsItem, &itemType, &rowsText, &r);
  252.     GetDItem (dp, colsItem, &itemType, &colsText, &r);
  253.  
  254.     NumToString (*rows, s);
  255.     SetIText (rowsText, s);
  256.  
  257.     NumToString (*cols, s);
  258.     SetIText (colsText, s);
  259.  
  260.     SelIText (dp, rowsItem, 0, 32767);
  261.  
  262.     GetDItem (dp, bModeItem, &itemType, (Handle *) &bButton, &r);
  263.     GetDItem (dp, gModeItem, &itemType, (Handle *) &gButton, &r);
  264.     GetDItem (dp, iModeItem, &itemType, (Handle *) &iButton, &r);
  265.     GetDItem (dp, cModeItem, &itemType, (Handle *) &cButton, &r);
  266.  
  267.     do
  268.         {
  269.         SetCtlValue (bButton, *mode == acquireModeBitmap);
  270.         SetCtlValue (gButton, *mode == acquireModeGrayScale);
  271.         SetCtlValue (iButton, *mode == acquireModeIndexedColor);
  272.         SetCtlValue (cButton, *mode == acquireModeRGBColor);
  273.  
  274.         ModalDialog (nil, &item);
  275.  
  276.         if (item >= bModeItem && item <= cModeItem)
  277.             *mode = item - bModeItem;
  278.  
  279.         if (item == OK)
  280.             {
  281.             GetIText (rowsText, s);
  282.             if (!ConvertString (s, rows))
  283.                 {
  284.                 SelIText (dp, rowsItem, 0, 32767);
  285.                 SysBeep (1);
  286.                 item = 0;
  287.                 }
  288.             }
  289.  
  290.         if (item == OK)
  291.             {
  292.             GetIText (colsText, s);
  293.             if (!ConvertString (s, cols))
  294.                 {
  295.                 SelIText (dp, colsItem, 0, 32767);
  296.                 SysBeep (1);
  297.                 item = 0;
  298.                 }
  299.             }
  300.  
  301.         }
  302.     while (item != OK && item != Cancel);
  303.  
  304.     DisposDialog (dp);
  305.     HPurge ((Handle) dt);
  306.  
  307.     return item == OK;
  308.     }
  309.  
  310. #undef dialogID
  311. #undef hookItem
  312. #undef rowsItem
  313. #undef colsItem
  314. #undef bModeItem
  315. #undef gModeItem
  316. #undef iModeItem
  317. #undef cModeItem
  318.  
  319. /*****************************************************************************/
  320.  
  321. /* Asks the user and the returns to the calling program the image parmaters. */
  322.  
  323. void DoStart (void)
  324.  
  325.     {
  326.     short j;
  327.  
  328.     gStuff->imageSize.v = gPermanent.lastRows;
  329.     gStuff->imageSize.h = gPermanent.lastCols;
  330.     gStuff->imageMode    = gPermanent.lastMode;
  331.  
  332.     if (!GetParameters (&gStuff->imageSize.v,
  333.                         &gStuff->imageSize.h,
  334.                         &gStuff->imageMode))
  335.         {
  336.         gResult = 1;
  337.         return;
  338.         }
  339.  
  340.     gPermanent.lastRows = gStuff->imageSize.v;
  341.     gPermanent.lastCols = gStuff->imageSize.h;
  342.     gPermanent.lastMode = gStuff->imageMode;
  343.  
  344.     gNextRow   = 0;
  345.     gNextPlane = 0;
  346.  
  347.     if (gStuff->imageMode == acquireModeBitmap)
  348.         gStuff->depth = 1;
  349.     else
  350.         gStuff->depth = 8;
  351.  
  352.     if (gStuff->imageMode == acquireModeRGBColor)
  353.         gStuff->planes = 3;
  354.     else
  355.         gStuff->planes = 1;
  356.  
  357.     if (gStuff->depth == 1)
  358.         {
  359.         gStuff->imageHRes = FixRatio (300, 1);
  360.         gStuff->imageVRes = FixRatio (300, 1);
  361.         }
  362.     else
  363.         {
  364.         gStuff->imageHRes = FixRatio (72, 1);
  365.         gStuff->imageVRes = FixRatio (72, 1);
  366.         }
  367.  
  368.     if (gStuff->imageMode == acquireModeIndexedColor)
  369.         for (j = 0; j < 256; j++)
  370.             {
  371.             gStuff->redLUT     [j] = j;
  372.             gStuff->greenLUT [j] = 255 - j;
  373.             gStuff->blueLUT  [j] = j;
  374.             }
  375.  
  376.     gStuff->data = nil;
  377.     }
  378.  
  379. /*****************************************************************************/
  380.  
  381. /* Returns the next hunk of the image to the calling program. */
  382.  
  383. void DoContinue (void)
  384.  
  385.     {
  386.     Ptr p;
  387.     short row;
  388.     short col;
  389.     long count;
  390.  
  391.     if (gStuff->data)
  392.         {
  393.         DisposPtr (gStuff->data);
  394.         gStuff->data = nil;
  395.         }
  396.  
  397.     if (gNextPlane != gStuff->planes)
  398.         {
  399.  
  400.         gStuff->colBytes = 1;
  401.  
  402.         if (gStuff->depth == 8)
  403.             gStuff->rowBytes = gStuff->imageSize.h;
  404.         else
  405.             gStuff->rowBytes = (gStuff->imageSize.h + 7) >> 3;
  406.  
  407.         gStuff->loPlane = gNextPlane;
  408.         gStuff->hiPlane = gNextPlane;
  409.  
  410.         count = gStuff->maxData / gStuff->rowBytes;
  411.  
  412.         if (count < 1)
  413.             {
  414.             gResult = memFullErr;
  415.             return;
  416.             }
  417.  
  418.         if (count > gStuff->imageSize.v - gNextRow)
  419.             count = gStuff->imageSize.v - gNextRow;
  420.  
  421.         gStuff->data = NewPtr (count * gStuff->rowBytes);
  422.  
  423.         if (!gStuff->data)
  424.             {
  425.             gResult = memFullErr;
  426.             return;
  427.             }
  428.  
  429.         SetRect (&gStuff->theRect,
  430.                  0,
  431.                  gNextRow,
  432.                  gStuff->imageSize.h,
  433.                  gNextRow + count);
  434.  
  435.         p = gStuff->data;
  436.  
  437.         for (row = gNextRow; row < gNextRow + count; row++)
  438.             {
  439.  
  440.             if (TestAbort ())
  441.                 {
  442.                 gResult = 1;
  443.                 return;
  444.                 }
  445.  
  446.             UpdateProgress (gNextPlane * ((long) gStuff->imageSize.v) + row,
  447.                             gStuff->planes * ((long) gStuff->imageSize.v));
  448.  
  449.             for (col = 0; col < gStuff->rowBytes; col++)
  450.                 {
  451.                 if (gStuff->depth == 1)
  452.                     *(p++) = 0xFF << (row & 7);
  453.                 else if (gStuff->planes == 1)
  454.                     *(p++) = row + col;
  455.                 else if (gNextPlane == 0)
  456.                     *(p++) = col;
  457.                 else if (gNextPlane == 1)
  458.                     *(p++) = row;
  459.                 else
  460.                     *(p++) = row + col;
  461.                 }
  462.  
  463.             }
  464.  
  465.         gNextRow = gNextRow + count;
  466.  
  467.         if (gNextRow == gStuff->imageSize.v)
  468.             {
  469.             gNextRow   = 0;
  470.             gNextPlane = gNextPlane + 1;
  471.             }
  472.  
  473.         }
  474.  
  475.     }
  476.  
  477. /*****************************************************************************/
  478.  
  479. /* This routine will always be called if DoStart does not return an error
  480.    (even if DoContinue returns an error or the user aborts the operation).
  481.    This allows the module to perform any needed cleanup. */
  482.  
  483. void DoFinish (void)
  484.  
  485.     {
  486.     if (gStuff->data)
  487.         {
  488.         DisposPtr (gStuff->data);
  489.         gStuff->data = nil;
  490.         }
  491.     }
  492.  
  493. /*****************************************************************************/
  494.  
  495. /* Main dispatching routine.  Initializes and sets up the global variables,
  496.    and performs the operation specified by the selector. */
  497.  
  498. pascal void main (selector, stuff, data, result)
  499.  
  500. short selector;
  501. AcquireRecordPtr stuff;
  502. long *data;
  503. short *result;
  504.  
  505.     {
  506.     Boolean firstTime;
  507.  
  508.     /* Allow access to global variables */
  509.  
  510.     RememberA0 ();
  511.     SetUpA4 ();
  512.  
  513.     /* Copy the current quickdraw globals into the plug-in local copy */
  514.  
  515.     asm
  516.         {
  517.             MOVE.L    (A5),A0         ; Get address of real quickdraw globals
  518.             SUB.L    #126,A0         ; Move to start
  519.             LEA     randSeed,A1     ; Get address of local copy
  520.             MOVE.W    #64,D0            ; Globals are 65 words long
  521.         @1    MOVE.W    (A0)+,(A1)+     ; Copy a word
  522.             DBF     D0,@1            ; Move to next word
  523.         }
  524.  
  525.     /* See if this is the first time called */
  526.  
  527.     if (!*data)
  528.         {
  529.  
  530.         /* Allocate a handle to hold permanent values */
  531.  
  532.         *data = (long) NewHandle (sizeof (TPermanent));
  533.  
  534.         if (!*data)
  535.             {
  536.             *result = memFullErr;
  537.             RestoreA4 ();
  538.             return;
  539.             }
  540.  
  541.         /* Initialize the permanent values */
  542.  
  543.         InitGlobals ();
  544.  
  545.         }
  546.  
  547.     /* Else restore permanent values */
  548.  
  549.     else
  550.         BlockMove (*((Handle) *data), (Ptr) &gPermanent, sizeof (TPermanent));
  551.  
  552.     /* Perform the requested operation */
  553.  
  554.     gStuff    = stuff;
  555.     gResult = noErr;
  556.  
  557.     switch (selector)
  558.         {
  559.  
  560.         case acquireSelectorAbout:
  561.             DoAbout ();
  562.             break;
  563.  
  564.         case acquireSelectorPrepare:
  565.             DoPrepare ();
  566.             break;
  567.  
  568.         case acquireSelectorStart:
  569.             DoStart ();
  570.             break;
  571.  
  572.         case acquireSelectorContinue:
  573.             DoContinue ();
  574.             break;
  575.  
  576.         case acquireSelectorFinish:
  577.             DoFinish ();
  578.             break;
  579.  
  580.         default:
  581.             gResult = acquireBadParameters;
  582.  
  583.         }
  584.  
  585.     *result = gResult;
  586.  
  587.     /* Save permanent values */
  588.  
  589.     BlockMove ((Ptr) &gPermanent, *((Handle) *data), sizeof (TPermanent));
  590.  
  591.     /* Restore the application's A4 register */
  592.  
  593.     RestoreA4 ();
  594.  
  595.     }
  596.